﻿using Mozi.HttpEmbedded.Encode;
using Mozi.HttpEmbedded.Extension;
using Mozi.HttpEmbedded.Generic;
using System;
using System.Collections.Generic;

namespace Mozi.Live.RTP
{
    /// <summary>
    /// RTCP SDES报文
    /// </summary>
    public class RTCPSourceDescriptionPackage : AbsRTCPPackage
    {
        /// <summary>
        /// 描述块合集
        /// </summary>
        public List<RTCPSourceDescriptionChunk> Chunks { get; set; }
        /// <summary>
        /// 包类型
        /// </summary>
        public override RTCPPackageType PackageType { get { return RTCPPackageType.SourceDescription; } set { return; } }
        /// <summary>
        /// 打包成数据流
        /// </summary>
        /// <returns></returns>
        public override byte[] Pack()
        {
            List<byte> buffer = new List<byte>();
            buffer.AddRange(PackHeader());
            if (Chunks != null)
            {
                foreach(var c in Chunks)
                {
                    buffer.AddRange(c.Pack());
                }
            }
            //最后计算长度
            byte[] data = buffer.ToArray();
            Length = (ushort)(data.Length / 4 - 1);
            Array.Copy(Length.ToBigEndian(), 0, data, 2, 2);
            return data;
        }
        /// <summary>
        /// 解析RTCP SDES报文
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static new RTCPSourceDescriptionPackage Parse(byte[] data)
        {
            RTCPSourceDescriptionPackage pack = new RTCPSourceDescriptionPackage();
            byte[] head = new byte[4];
            Array.Copy(data, 0, head, 0, 4);
            pack.ParseHeader(head);
            pack.Chunks = new List<RTCPSourceDescriptionChunk>();

            int offset = 4;
            for (int i = 0; i < pack.ReportCount; i++)
            {
                var chunk = new RTCPSourceDescriptionChunk()
                {
                    Identifier = data.GetBigEndianUInt32(offset),
                    Items=new List<RTCPSourceDescriptionItem>()
                };
                offset += 4;
                pack.Chunks.Add(chunk);
                while (offset< pack.Length)
                {
                    RTCPSourceDescriptionItem item = new RTCPSourceDescriptionItem();
                    byte st = data[offset];
                    item.ItemType = RTCPSourceDescriptionType.Get<RTCPSourceDescriptionType>(st.ToString());
                    
                    byte length = data[offset + 1];
                    item.Length = length;
                    byte[] arrContent = new byte[length];
                    Array.Copy(data, offset + 1 + 1, arrContent, 0, length);
                    offset += 1 + 1 + length;
                    item.Value = StringEncoder.Decode(arrContent);
                    chunk.Items.Add(item);
                }
            }
            return pack;
        }
    }
    /// <summary>
    /// 源描述块
    /// </summary>
    public class RTCPSourceDescriptionChunk
    {
        /// <summary>
        /// 源标识符 同步源|贡献源
        /// </summary>
        public uint Identifier { get; set; }
        /// <summary>
        /// 项集合
        /// </summary>
        public List<RTCPSourceDescriptionItem> Items { get; set; }
        /// <summary>
        /// 打包成字节流
        /// </summary>
        /// <returns></returns>
        public byte[] Pack()
        {
            List<byte> buffer = new List<byte>();
            buffer.AddRange(Identifier.ToBigEndian());
            if (Items != null)
            {
                foreach (var r in Items)
                {
                    buffer.Add(r.ItemType.Value);
                    //TODO 这里未截取字符串长度
                    byte[] text = StringEncoder.Encode(r.Value);
                    buffer.Add((byte)(text.Length > 255 ? 255 : text.Length));
                    buffer.AddRange(text);
                }
            }
            return buffer.ToArray();
        }
    }
    /// <summary>
    /// 源描述项
    /// </summary>
    public class RTCPSourceDescriptionItem
    {
        /// <summary>
        /// 8bits
        /// </summary>
        public RTCPSourceDescriptionType ItemType { get; set; }
        /// <summary>
        /// 数据长度
        /// </summary>
        public byte Length { get; set; }
        /// <summary>
        /// 值 ASCII类型
        /// </summary>
        public string Value { get; set; }
    }
    /// <summary>
    /// 源描述项类型
    /// </summary>
    public class RTCPSourceDescriptionType : AbsClassEnum
    {
        private string _name = "";
        private byte _typeValue;

        public static RTCPSourceDescriptionType CName = new RTCPSourceDescriptionType("CNAME", 1);
        public static RTCPSourceDescriptionType UserName = new RTCPSourceDescriptionType("NAME", 2);
        public static RTCPSourceDescriptionType EMail = new RTCPSourceDescriptionType("EMAIL", 3);
        public static RTCPSourceDescriptionType Phone = new RTCPSourceDescriptionType("PHONE", 4);
        public static RTCPSourceDescriptionType Location = new RTCPSourceDescriptionType("LOC", 5);
        public static RTCPSourceDescriptionType Tool = new RTCPSourceDescriptionType("TOOL", 6);
        public static RTCPSourceDescriptionType Notice = new RTCPSourceDescriptionType("NOTE", 7);
        public static RTCPSourceDescriptionType PrivateExtension = new RTCPSourceDescriptionType("PRIV", 8);

        /// <summary>
        /// 消息类型值
        /// </summary>
        public byte Value
        {
            get
            {
                return _typeValue;
            }
        }
        /// <summary>
        /// 消息类型名
        /// </summary>
        public string Name
        {
            get { return _name; }
        }
        /// <summary>
        /// 唯一标识符号
        /// </summary>
        protected override string Tag
        {
            get
            {
                return _typeValue.ToString();
            }
        }

        internal RTCPSourceDescriptionType(string name, byte typeValue)
        {
            _name = name;
            _typeValue = typeValue;
        }
    }
}
